home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / Shells / tcsh / Source / sh.hist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  7.7 KB  |  352 lines

  1. /* $Header: /u/christos/src/tcsh-6.03/RCS/sh.hist.c,v 3.6 1992/10/05 02:41:30 christos Exp $ */
  2. /*
  3.  * sh.hist.c: Shell history expansions and substitutions
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "sh.h"
  38.  
  39. RCSID("$Id: sh.hist.c,v 3.6 1992/10/05 02:41:30 christos Exp $")
  40.  
  41. #include "tc.h"
  42.  
  43. extern bool histvalid;
  44. extern Char histline[];
  45. Char HistLit = 0;
  46.  
  47. static    void    hfree    __P((struct Hist *));
  48. static    void    dohist1    __P((struct Hist *, int *, int));
  49. static    void    phist    __P((struct Hist *, int));
  50.  
  51. #define HIST_ONLY    0x01
  52. #define HIST_SAVE    0x02
  53. #define HIST_LOAD    0x04
  54. #define HIST_REV    0x08
  55. #define HIST_CLEAR    0x10
  56.  
  57. /*
  58.  * C shell
  59.  */
  60.  
  61. void
  62. savehist(sp)
  63.     struct wordent *sp;
  64. {
  65.     register struct Hist *hp, *np;
  66.     register int histlen = 0;
  67.     Char   *cp;
  68.  
  69.     /* throw away null lines */
  70.     if (sp->next->word[0] == '\n')
  71.     return;
  72.     cp = value(STRhistory);
  73.     if (*cp) {
  74.     register Char *p = cp;
  75.  
  76.     while (*p) {
  77.         if (!Isdigit(*p)) {
  78.         histlen = 0;
  79.         break;
  80.         }
  81.         histlen = histlen * 10 + *p++ - '0';
  82.     }
  83.     }
  84.     for (hp = &Histlist; (np = hp->Hnext) != NULL;)
  85.     if (eventno - np->Href >= histlen || histlen == 0)
  86.         hp->Hnext = np->Hnext, hfree(np);
  87.     else
  88.         hp = np;
  89.     (void) enthist(++eventno, sp, 1);
  90. }
  91.  
  92. struct Hist *
  93. enthist(event, lp, docopy)
  94.     int     event;
  95.     register struct wordent *lp;
  96.     bool    docopy;
  97. {
  98.     extern time_t Htime;
  99.     register struct Hist *np = (struct Hist *) xmalloc((size_t) sizeof(*np));
  100.  
  101.     /* Pick up timestamp set by lex() in Htime if reading saved history */
  102.     if (Htime != (time_t) 0) {
  103.     np->Htime = Htime;
  104.     Htime = 0;
  105.     }
  106.     else
  107.     (void) time(&(np->Htime));
  108.  
  109.     np->Hnum = np->Href = event;
  110.     if (docopy) {
  111.     copylex(&np->Hlex, lp);
  112.     if (histvalid)
  113.         np->histline = Strsave(histline);
  114.     else
  115.         np->histline = NULL;
  116.     }
  117.     else {
  118.     np->Hlex.next = lp->next;
  119.     lp->next->prev = &np->Hlex;
  120.     np->Hlex.prev = lp->prev;
  121.     lp->prev->next = &np->Hlex;
  122.     np->histline = NULL;
  123.     }
  124.     np->Hnext = Histlist.Hnext;
  125.     Histlist.Hnext = np;
  126.     return (np);
  127. }
  128.  
  129. static void
  130. hfree(hp)
  131.     register struct Hist *hp;
  132. {
  133.  
  134.     freelex(&hp->Hlex);
  135.     if (hp->histline)
  136.     xfree((ptr_t) hp->histline);
  137.     xfree((ptr_t) hp);
  138. }
  139.  
  140.  
  141. /*ARGSUSED*/
  142. void
  143. dohist(vp, c)
  144.     Char  **vp;
  145.     struct command *c;
  146. {
  147.     int     n, hflg = 0;
  148.  
  149.     if (getn(value(STRhistory)) == 0)
  150.     return;
  151.     if (setintr)
  152. #ifdef BSDSIGS
  153.     (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
  154. #else
  155.     (void) sigrelse(SIGINT);
  156. #endif
  157.     while (*++vp && **vp == '-') {
  158.     Char   *vp2 = *vp;
  159.  
  160.     while (*++vp2)
  161.         switch (*vp2) {
  162.         case 'c':
  163.         hflg |= HIST_CLEAR;
  164.         break;
  165.         case 'h':
  166.         hflg |= HIST_ONLY;
  167.         break;
  168.         case 'r':
  169.         hflg |= HIST_REV;
  170.         break;
  171.         case 'S':
  172.         hflg |= HIST_SAVE;
  173.         break;
  174.         case 'L':
  175.         hflg |= HIST_LOAD;
  176.         break;
  177.         default:
  178.         stderror(ERR_HISTUS, "chrSL");
  179.         break;
  180.         }
  181.     }
  182.  
  183.     if (hflg & HIST_CLEAR) {
  184.     struct Hist *np, *hp;
  185.     for (hp = &Histlist; (np = hp->Hnext) != NULL;)
  186.         hp->Hnext = np->Hnext, hfree(np);
  187.     }
  188.  
  189.     if (hflg & HIST_LOAD) {
  190.     loadhist(*vp);
  191.     return;
  192.     }
  193.     else if (hflg & HIST_SAVE) {
  194.     rechist(*vp);
  195.     return;
  196.     }
  197.     if (*vp)
  198.     n = getn(*vp);
  199.     else {
  200.     n = getn(value(STRhistory));
  201.     }
  202.     dohist1(Histlist.Hnext, &n, hflg);
  203. }
  204.  
  205. static void
  206. dohist1(hp, np, hflg)
  207.     struct Hist *hp;
  208.     int    *np, hflg;
  209. {
  210.     bool    print = (*np) > 0;
  211.  
  212.     for (; hp != 0; hp = hp->Hnext) {
  213.     (*np)--;
  214.     hp->Href++;
  215.     if ((hflg & HIST_REV) == 0) {
  216.         dohist1(hp->Hnext, np, hflg);
  217.         if (print)
  218.         phist(hp, hflg);
  219.         return;
  220.     }
  221.     if (*np >= 0)
  222.         phist(hp, hflg);
  223.     }
  224. }
  225.  
  226. static void
  227. phist(hp, hflg)
  228.     register struct Hist *hp;
  229.     int     hflg;
  230. {
  231.  
  232.     if (hflg != HIST_ONLY) {
  233.     Char   *cp = str2short("%h\t%T\t%R\n");
  234.     Char buf[BUFSIZE];
  235.     struct varent *vp = adrof(STRhistory);
  236.  
  237.     if (vp && vp->vec[0] && vp->vec[1])
  238.         cp = vp->vec[1];
  239.  
  240.     tprintf(FMT_HISTORY, buf, cp, BUFSIZE, NULL, hp->Htime, (ptr_t) hp);
  241.     for (cp = buf; *cp;)
  242.         xputchar(*cp++);
  243.     }
  244.     else {
  245.     /* 
  246.      * Make file entry with history time in format:
  247.      * "+NNNNNNNNNN" (10 digits, left padded with ascii '0') 
  248.      */
  249.     xprintf("#+%010lu\n", hp->Htime);
  250.  
  251.     if (HistLit && hp->histline)
  252.         xprintf("%S\n", hp->histline);
  253.     else
  254.         prlex(&hp->Hlex);
  255.     }
  256. }
  257.  
  258.  
  259. void
  260. fmthist(fmt, ptr, buf)
  261.     int fmt;
  262.     ptr_t ptr;
  263.     char *buf;
  264. {
  265.     struct Hist *hp = (struct Hist *) ptr;
  266.     switch (fmt) {
  267.     case 'h':
  268.     xsprintf(buf, "%6d", hp->Hnum);
  269.     break;
  270.     case 'R':
  271.     if (HistLit && hp->histline)
  272.         xsprintf(buf, "%S", hp->histline);
  273.     else {
  274.         Char ibuf[BUFSIZE], *ip;
  275.         char *p;
  276.         (void) sprlex(ibuf, &hp->Hlex);
  277.         for (p = buf, ip = ibuf; (*p++ = *ip++) != '\0'; )
  278.         continue;
  279.     }
  280.     break;
  281.     default:
  282.     buf[0] = '\0';
  283.     break;
  284.     }
  285.     
  286. }
  287.  
  288. void
  289. rechist(fname)
  290.     Char *fname;
  291. {
  292.     Char    buf[BUFSIZE], hbuf[BUFSIZE];
  293.     int     fp, ftmp, oldidfds;
  294.     extern  int fast;
  295.     struct  varent *shist;
  296.     static Char   *dumphist[] = {STRhistory, STRmh, 0, 0};
  297.  
  298.     if (!fast) {
  299.     /*
  300.      * If $savehist is just set, we use the value of $history
  301.      * else we use the value in $savehist
  302.      */
  303.     if ((shist = adrof(STRsavehist)) != NULL) {
  304.         if (shist->vec[0][0] != '\0')
  305.         (void) Strcpy(hbuf, shist->vec[0]);
  306.         else if ((shist = adrof(STRhistory)) != 0 && 
  307.              shist->vec[0][0] != '\0')
  308.         (void) Strcpy(hbuf, shist->vec[0]);
  309.         else
  310.         return;
  311.     }
  312.     else
  313.         return;
  314.  
  315.     if (fname == NULL) 
  316.         if ((fname = value(STRhistfile)) == STRNULL) {
  317.         fname = Strcpy(buf, value(STRhome));
  318.         (void) Strcat(buf, &STRtildothist[1]);
  319.         }
  320.  
  321.     fp = creat(short2str(fname), 0600);
  322.     if (fp == -1) 
  323.         return;
  324.     oldidfds = didfds;
  325.     didfds = 0;
  326.     ftmp = SHOUT;
  327.     SHOUT = fp;
  328.     dumphist[2] = hbuf;
  329.     dohist(dumphist, NULL);
  330.     (void) close(fp);
  331.     SHOUT = ftmp;
  332.     didfds = oldidfds;
  333.     }
  334. }
  335.  
  336.  
  337. void
  338. loadhist(fname)
  339.     Char *fname;
  340. {
  341.     static Char   *loadhist_cmd[] = {STRsource, STRmh, NULL, NULL};
  342.  
  343.     if (fname != NULL)
  344.     loadhist_cmd[2] = fname;
  345.     else if ((fname = value(STRhistfile)) != STRNULL)
  346.     loadhist_cmd[2] = fname;
  347.     else
  348.     loadhist_cmd[2] = STRtildothist;
  349.  
  350.     dosource(loadhist_cmd, NULL);
  351. }
  352.